package com.fary.chapter04_executors;


import org.junit.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Fary
 * @version 1.0
 * @date 2021/8/3 9:06
 * 线程池底层 提前创建好固定大小的线程 一直在运行状态
 * 停止线程池 cas 基本上 在 juc并发包 修改操作 cas
 * 线程池状态--SHUTDOWN  线程池停止 不会继续接受新的线程任务但是 线程池内部中还有没执行完毕的线程任务 存放阻塞队列中
 * 纯手写线程 提前创建好固定大小的线程 一直运行状态
 * 线程池内部 懒加载
 *
 * workQueue 存放  缓存的 线程任务 workers 存放 一直正在运行线程（核心线程数）
 */
public class TestExecutor {

    /**
     * 实际的项目中 使用多线程 禁止new线程  必须结合线程池使用
     * 上下文
     * 线程准备就绪状态 开始被cpu调度执行
     * 果开启了一个线程
     * 需要时间
     * 新建状态→就绪状态→cpu调度执行→运行状态→ 线程run方法代码
     */
    @Test
    public void test1() throws Exception {
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("实际的项目中 使用多线程 禁止new线程  必须结合线程池使用");
                }
            }).start();
        }
    }

    @Test
    public void test2() throws Exception {
        // 创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            int finalI1 = i;
            executorService.execute(() -> System.out.println("缓存线程池"+ Thread.currentThread().getName() + "i:" + finalI1));
        }
        System.out.println();
    }

    @Test
    public void test3() throws Exception {
        // 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
        ExecutorService executorService2 = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 10; i++) {
            int finalI1 = i;
            executorService2.execute(() -> System.out.println("定长线程池"+ Thread.currentThread().getName() + "i:" + finalI1));
        }
    }

    @Test
    public void test4() throws Exception {
        // 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
        ExecutorService executorService3 = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            int finalI1 = i;
            executorService3.execute(() -> System.out.println("单例线程池"+ Thread.currentThread().getName() + "i:" + finalI1));
        }
    }

    @Test
    public void test5() throws Exception {
        // 创建一个定时线程池，支持定时及周期性任务执行。
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            scheduledExecutorService.schedule(() -> System.out.println("定时线程池"+ Thread.currentThread().getName() + "i:" + finalI), 1, TimeUnit.SECONDS);
        }
        Thread.sleep(60000);
    }

    /**
     * 定时任务线程池
     * @throws Exception
     */
    @Test
    public void test30() throws Exception {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {//每隔一段时间就触发异常
            @Override
            public void run() {
                System.out.println("================");
            }
        }, 1, 5, TimeUnit.SECONDS);

        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {//每隔一段时间打印系统时间，证明两者是互不影响的
            @Override
            public void run() {
                System.out.println(System.nanoTime());
            }
        }, 1, 2, TimeUnit.SECONDS);
        Thread.sleep(60000);
    }
}
